package com.lutzyt.delivery.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lutzyt.delivery.bean.DiscountCoupon;
import com.lutzyt.delivery.bean.DiscountCouponItem;
import com.lutzyt.delivery.mapper.DiscountCouponDAO;
import com.lutzyt.delivery.service.DiscountCouponItemService;
import com.lutzyt.delivery.service.DiscountCouponService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author zyt
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class DiscountCouponServiceImpl extends ActionServiceImpl<DiscountCouponDAO, DiscountCoupon> implements DiscountCouponService {

  private DiscountCouponDAO discountCouponDAO;
  private DiscountCouponItemService itemService;

  @PostConstruct
  private void init(){
    setOnStr("该优惠券已经发布，请不要重复操作");
    setOffStr("该优惠券已经下架，请不要重复操作");
  }

  @Transactional(readOnly = true)
  @Override
  public DiscountCoupon findById(Integer id) {
    return discountCouponDAO.selectById(id);
  }

  @Transactional(readOnly = true)
  @Override
  public IPage<DiscountCoupon> findByPage(int pageNum, int pageSize) {
    return discountCouponDAO.selectPage(new Page<>(pageNum, pageSize), new QueryWrapper<>());
  }

  @Override
  public List<DiscountCoupon> drawList() {
    QueryWrapper<DiscountCoupon> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("state", "on");
    queryWrapper.eq("audit", "PASS");
    queryWrapper.gt("end_date", new Date());

    return discountCouponDAO.selectList(queryWrapper);
  }

  @Override
  public void insert(DiscountCoupon discountCoupon) {
    discountCouponDAO.insert(discountCoupon);
  }

  @Override
  public void update(DiscountCoupon discountCoupon) {
    discountCouponDAO.updateById(discountCoupon);
  }

  @Override
  public void deleteById(Integer id) {
    discountCouponDAO.deleteById(id);
  }

  @Override
  public void deleteByIds(List<String> ids) {
    discountCouponDAO.deleteBatchIds(ids);
  }

  @Override
  public List<String> findIdsByCustomerId(Integer id) {
    final List<DiscountCouponItem> list = itemService.lambdaQuery().eq(DiscountCouponItem::getCustomerId, id).list();
    final List<String> discountCouponIds = list.stream().map(DiscountCouponItem::getDiscountCouponId).map(String::valueOf).collect(Collectors.toList());
    return discountCouponIds;
  }

  @Override
  public List<DiscountCoupon> findByCustomerId(Integer id) {
    // 查出自己拥有的优惠券
    final List<DiscountCouponItem> itemList = itemService.lambdaQuery().eq(DiscountCouponItem::getCustomerId, id).list();
    // 转换成 优惠券Id:优惠券状态 键值对
    final Map<Integer, String> map = itemList.stream().collect(Collectors.toMap(DiscountCouponItem::getDiscountCouponId, DiscountCouponItem::getState,(listSubOld, listSubNew) -> listSubNew));
    // 查出优惠券详细信息
    final List<DiscountCoupon> discountList = this.lambdaQuery().in(DiscountCoupon::getId, map.keySet()).list();
    // 循环改变状态
    discountList.forEach(discountCoupon -> {
      // 状态
      String state = map.get(discountCoupon.getId());
      discountCoupon.setState(state);
    });
    discountList.sort((o1, o2) -> {
      if ("UNUSED".equals(o1.getState())) {
        return 1;
      }
      return -1;
    });
    return discountList;
  }

  @Override
  public List<DiscountCoupon> findUnusedByCustomerId(Integer id) {
    final List<Integer> ids = itemService.lambdaQuery()
        .eq(DiscountCouponItem::getCustomerId, id)
        .eq(DiscountCouponItem::getState, "UNUSED")
        .list().stream().map(DiscountCouponItem::getDiscountCouponId).collect(Collectors.toList());
    // 查出优惠券详细信息
    final List<DiscountCoupon> discountList = this.lambdaQuery()
        .gt(DiscountCoupon::getEndDate, new Date())
        .in(DiscountCoupon::getId, ids).list();
    return discountList;
  }

  @Autowired
  public void setItemService(DiscountCouponItemService itemService) {
    this.itemService = itemService;
  }

  @Autowired
  public void setDiscountCouponDAO(DiscountCouponDAO discountCouponDAO) {
    this.discountCouponDAO = discountCouponDAO;
  }
}